#pragma once

#include <iostream>
#include <string>
#include <cstdio>
#include <functional>

#define SPA " "
#define SPALENGTH strlen(SPA)

#define NEWLINE "\r\n"
#define NEWLINELENGTH strlen(NEWLINE)
//这个文件和那边的类没有半毛钱关系，所以我们之间放到这里来

//serverio是回调函数
// void serverio(int sock)
// {
//      //为该客户提供服务
//      char buffer[1024];
//      while(1)
//      {
//          //接收信息

//          ssize_t n= read(sock, buffer,sizeof(buffer) - 1);
//         // std::cout << "buffer = " << buffer << std::endl;

//          if(n > 0)
//          {
//              //read完成后要给对方回信息
//             // buffer[strlen (buffer) - 1 ] = 0;
//              //std::string response = "我是服务器，好的我现在收到了你的信息";
//              buffer[n] = 0;
//              std::cout << buffer << std::endl;

//              std::string str = buffer;
//              //str += "返回给客户端#" ;

//               write(sock,str.c_str(),str.size());
//               //write(sock,buffer,sizeof (buffer));

//               if( n == - 1)
//               {
//                  //logmessage("fatal",getpid(),"write failed");
//                  exit(4);
//               }
//               //logmessage("write",getpid(),"write sucess");
//          }
//          else if(n == 0)
//          {
//              //说明客户端已经退出，我也可以退出了
//              std::cout << "Cilent quie me too!" << std::endl;
//              break;
//          }
//          //发送信息
//      }
// }
class Request;
class Response;

//0正常，1除零错误，2取模错误，3错误的操作符
void calculate(const Request& req,Response& rsp)
{
    char op = req._op;

    switch(op)
    {
        case '+':
        {
            rsp._result =  req._x + req._y;
            rsp._exitcode = 0;
            break;
        } 
        case '-':
        {
            rsp._result = req._x - req._y;
            rsp._exitcode = 0;  
            break;
        }

        case '/':
        {
            if(req._y == 0)
            {
                rsp._exitcode = 1;
            }
            else
            {
                rsp._result = req._y / req._x;
                rsp._exitcode = 0;
            }
        }
        case '%':

        if(req._y == 0)
        {
            rsp._exitcode = 2;
        }
        else
        {
            rsp._result = req._y % req._x;
            rsp._exitcode = 0;
        }
        break;
        

        default:
        rsp._exitcode = 3;
     }

}


class Request
{
public:
    Request()
    {}

    Request(const int x , const char op,const int y):_x(x),_y(y),_op(op)
    {}

    // x op y\r\n
    bool serilize(std::string *out)
    {
        *out = "";
        std::string x_string = std::to_string(_x);
        std::string y_string = std::to_string(_y);

        *out += x_string;
        *out += SPA;
        *out += y_string;
        *out += SPA;
        *out += NEWLINE;
    }

    //对面随便new一个Request然后desserilize进行赋值
    //x op y\r\n

    bool deserilize(std::string& str)
    {
         auto left = str.find(SPA);
         auto right = str.rfind(SPA);

         if(left == std::string::npos || right == std::string::npos) return false;
         if(left == right) return false;

         std::string x_string = str.substr(0,left);
         std::string y_string = str.substr(right+1,str.size()-(right+1)-NEWLINELENGTH);
         std::string op_string = str.substr(left+1,1);

         _x = atoi(x_string.c_str());
         _y = atoi(y_string.c_str());
         _op = op_string[0];

         return true;
    }

public:
    int _x;
    int _y;
    char _op;
};


class Response
{
public:
   Response()
   {}
 
   //exitcode result
   bool serilize(std::string *out)
   {
       *out = "";
       std::string x_string = std::to_string(_exitcode);
       std::string y_string = std::to_string(_result);

       *out += x_string;
       *out += SPA;
       *out += y_string;
   }
  
   bool deserlize(std::string& str)
   {
        auto sign = str.find(SPA);
  
        if(sign == std::string::npos) return false;
        
    
        _exitcode = atoi(str.substr(0,sign).c_str());
        _result = atoi(str.substr(sign+1).c_str());
        return true;
   }

public:
    int _exitcode;
    int _result;
};



class Task
{
    //using func_t = std::function<bool(int)>;

    typedef bool(*func_t)(int);
public:

    Task()
    {}


    Task(int sock,func_t func)
        :_sock(sock), _callback(func)
    {}

    void operator()()
    {
        _callback(_sock);
    }

private:
    int _sock;
    func_t _callback;
};